#pragma once
#include "XmlConfigAdapter.h"

struct sEdit
{
    typedef std::map<CString, CString> MapStrData;
    MapStrData m_MapData;
    enum CtrlType
    {
        E_Null,
        E_bool,
        E_edit,
        E_combo,
        E_list,
		E_combo_user,
        E_check_list,
        E_spell_cast,
    };
    //CString key, title, combo, data;
    CtrlType type;
    CString Data(CString str)
    {
        MapStrData::iterator itr = m_MapData.find(str);
        if (itr==m_MapData.end())
            return _T("");
        return itr->second;
    }
    void Init(CString& str)
    {
        int iStart = 0;
        CString strItem;
        while(1)
        {
            strItem = str.Tokenize(_T("\r\n"), iStart);
            if (iStart==-1) break;
            int i = strItem.Find(_T("="));
            m_MapData[strItem.Left(i)] = strItem.Mid(i+1);

        }
        if (m_MapData[_T("TYPE")]==_T("bool"))
        {
            type = E_bool;
        }
        else if (m_MapData[_T("TYPE")]==_T("Edit"))
        {
            type = E_edit;
        }
        else if (m_MapData[_T("TYPE")]==_T("List"))
        {
            type = E_list;
        }
        else if (m_MapData[_T("TYPE")]==_T("Combo"))
        {
            type = E_combo;
        }
        else if (m_MapData[_T("TYPE")]==_T("ComboUser"))
        {
            type = E_combo_user;
        }
        else if (m_MapData[_T("TYPE")]==_T("CheckList"))
        {
            type = E_check_list;
        }
        else if (m_MapData[_T("TYPE")]==_T("SpellCast"))
        {
            type = E_spell_cast;
        }        
    }

};
class CUserInfo
{
    enum{ eName=0, ePwd=128, eIndex=251, eSave=255};
    CHAR _Buf[256];
public:
    CUserInfo(){ZeroMemory(_Buf, sizeof(_Buf));}
    ~CUserInfo(){}
    void Init(HANDLE hData)
    {
        memcpy(_Buf, hData, sizeof(CUserInfo));
    }
    const HANDLE DataPtr() const
    {
        return (const HANDLE)_Buf;
    }
    CString User() const
    {
        return CString(&_Buf[eName]);
    }
    CString Password() const
    {
        return CString(&_Buf[ePwd]);
    }
    bool IsSaved() const
    {
        return !!_Buf[eSave];
    }

    int Index() const
    {
        const int *pIndex = (const int *)&_Buf[eIndex];
        return *pIndex;
    }

    bool operator ==(const CUserInfo& T)const
    {
        return T.User()==User();
    }


    void SaveInfo(CString User, CString Pwd, bool Save, int Index)
    {
        CStringA strUser(User);
        CStringA strPwd(Pwd);
        lstrcpyA(_Buf+eName, strUser.GetString());
        lstrcpyA(_Buf+ePwd, strPwd.GetString());
        *( (int*)&_Buf[eIndex] ) = Index;
        _Buf[eSave] = Save;
    }

    static bool ReadData(std::map<int, CUserInfo>& vecData);
    static bool WriteData(std::map<int, CUserInfo>& vecData);

};
struct sSpellData;
class CSpellCast
{
    std::map<CString, CString> s_SpellCast;
    void ParseSpell(CString strFile)
    {
        CString strPath = ModulePath()+c_SpellCast+strFile;
        
        HANDLE hFile = ::CreateFile(strPath.GetString(), 
            GENERIC_READ, 
            FILE_SHARE_READ,
            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile==INVALID_HANDLE_VALUE) return;

        DWORD dwSize = ::GetFileSize(hFile, NULL);
        if (dwSize==0) return;
        TCHAR* BufTmp = new TCHAR[dwSize/sizeof(TCHAR)+1];
        memset(BufTmp, 0, dwSize+2);
        ::ReadFile(hFile, BufTmp, dwSize, &dwSize, 0);
        ::CloseHandle(hFile);
        {
            CString str(BufTmp+1);
            int iStart = 0;
            CString strItem;
            CString strData;
            while(1)
            {
                strItem = str.Tokenize(_T("\r\n"), iStart);
                if (iStart==-1) break;
                int i = strItem.Find(_T("="));
                strData += strItem.Left(i) + _T("|");
                //MapTable[strItem.Left(i)] = strItem.Mid(i+1);
            }
            s_SpellCast[strFile] = strData;
        }
        delete []BufTmp;
    }
public:
    CSpellCast()
    {
        CString strFind = ModulePath()+c_SpellCast+_T("*.txt");
        WIN32_FIND_DATA wfd;
        HANDLE hFind;

        hFind = ::FindFirstFile(strFind, &wfd);
        if(hFind != INVALID_HANDLE_VALUE)
        {
            CString tFileName(wfd.cFileName, lstrlen(wfd.cFileName)-4);
            ParseSpell(wfd.cFileName);
            while(::FindNextFile(hFind,&wfd))
            {

                ParseSpell(wfd.cFileName);
            }
            ::FindClose(hFind);
        }
    }

    CString GetData(CString strKey)
    {
        return s_SpellCast[strKey];
    }
};

class CIPDatas
{
    typedef std::vector<CString> VecStr;
    VecStr m_Data;
    VecStr m_Key;
    CString m_strHome;
    CString m_strRegister;
    CString m_strFormat;
    CString m_strFormat1;
    CString m_strID;
public:
    CIPDatas()
    {
        Init();
    }
    enum E_KEY
    {
        eOK=__LINE__,
        eNOUSER,
        eERRORPWD,
        eNOMONEY,
        eLOCKED,
        eUSERPAUSE,
        eLATER,
        eERRORSERVER,
        eCERROR,
    };
    void Init();
    DWORD Size()
    {
        return m_Data.size();
    }
    CString GetIP( DWORD index)
    {
        if (index<Size())
            return m_Data[index];
        return _T("");
    }
    CString GetKey( E_KEY e)
    {
        DWORD i = (int)e-eOK;
        if ((DWORD)i<m_Key.size())
            return m_Key[i];
        return _T("");
    }
    CString GetHome()
    {
        return m_strHome;
    }
    CString GetID()
    {
        return m_strID;
    }
    CString GetRegister()
    {
        return m_strRegister;
    }
    CString GetFormat()
    {
        return m_strFormat;
    }
    CString GetFormat1()
    {
        return m_strFormat1;
    }
};

class CDataSeting
{
    CUserInfo m_LastLogin;
    std::map<HTREEITEM, sEdit> s_Data;
    std::map<CString, CString> s_Seting;
    std::map<int, CUserInfo> s_mapUserInfo;
    CXmlConfigAdapter m_oAdapter;
    CSpellCast m_oSpellCast;
    CIPDatas m_oIPData;
    friend CDataSeting &Data();
    CDataSeting();
    ~CDataSeting()
    {
        //CUserInfo::WriteData(s_mapUserInfo);
    }
public:
    void Init(LPCTSTR lpszName);
    void Create(LPCTSTR lpszName);

    void UpdateData();

    void AddItem(HTREEITEM hItem, CString &strData);
	void AddItem(HTREEITEM hItem, sEdit& o);
    sEdit GetItem(HTREEITEM hItem);

    CString GetData(CString &strKey);
    CString GetData(LPTSTR strKey);
    CString GetSpellCast(CString &strKey);
    void SetData(CString &strKey, LPTSTR strData);
    void SetData(CString &strKey, CString &strData);
    void SetIni(const CString &strKey, CString &strData);
    void SaveData();

    int GetUserCount() const{ return (int)s_mapUserInfo.size();}
    CUserInfo GetUser(int index);
    void AddUser(int index, CUserInfo& user);
    CUserInfo GetLastLogin() { return m_LastLogin; }
    void SetLastLogin(CUserInfo& L) { m_LastLogin = L;}
    CIPDatas&GetIPData(){ return m_oIPData; };
};

CDataSeting &Data();